package com.aurora.app.controller.weixin;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.aurora.app.constant.Conf;
import com.aurora.app.constant.PayConfig;
import com.aurora.app.entity.PayOrder;
import com.aurora.app.entity.Thing;
import com.aurora.app.entity.User;
import com.aurora.app.entity.UserAccount;
import com.aurora.app.entity.WeixinAppToken;
import com.aurora.app.enums.PayState;
import com.aurora.app.exption.NullEntityException;
import com.aurora.app.service.PayOrderService;
import com.aurora.app.service.ThingService;
import com.aurora.app.service.UserAccountService;
import com.aurora.app.service.UserService;
import com.aurora.app.service.WeixinAppTokenService;
import com.aurora.app.util.SendTemplate;
import com.aurora.app.util.weixin.PayUtils;
import com.aurora.app.util.weixin.XmlUtils;

/**
 * 微信支付
 * 
 * @author yongjiang.lin
 *
 */
@Controller
@RequestMapping(value = "api/pay")
public class PayOrderController {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	@Resource
	private PayOrderService payOrderService;
	@Resource
	private UserAccountService userAccountService;
	@Resource
	private UserService userService;
	@Resource
	private WeixinAppTokenService weixinAppTokenService;
	
	/**
	 * 用户支付后的异步回调
	 * 
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
	@RequestMapping(value = "/back/notify")
	public void backNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 读取参数
		InputStream inputStream;
		StringBuffer sb = new StringBuffer();
		inputStream = request.getInputStream();
		String s;
		BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
		while ((s = in.readLine()) != null) {
			sb.append(s);
		}
		in.close();
		inputStream.close();

		// 解析xml成map
		Map<String, String> m = new HashMap<String, String>();
		m = XmlUtils.xmlToMap(sb.toString());

		// 过滤空 设置 TreeMap
		SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
		Iterator it = m.keySet().iterator();
		while (it.hasNext()) {
			String parameter = (String) it.next();
			String parameterValue = m.get(parameter);

			String v = "";
			if (null != parameterValue) {
				v = parameterValue.trim();
			}
			packageParams.put(parameter, v);
		}

		// 商户支付密钥Key
		String key = PayConfig.KEY; // key

		
		// ------------------------------
		// 处理业务开始
		// ------------------------------
		String resXml = "";
		if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
			// 这里是支付成功
			////////// 执行自己的业务逻辑////////////////
			String mch_id = (String) packageParams.get("mch_id");
			String openid = (String) packageParams.get("openid");
			String is_subscribe = (String) packageParams.get("is_subscribe");
			String out_trade_no = (String) packageParams.get("out_trade_no");

			String total_fee = (String) packageParams.get("total_fee");

			logger.info("mch_id:" + mch_id);
			logger.info("openid:" + openid);
			logger.info("is_subscribe:" + is_subscribe);
			logger.info("out_trade_no:" + out_trade_no);
			logger.info("total_fee:" + total_fee);

			////////// 执行自己的业务逻辑////////////////
			User user = this.userService.getBaseDao().find("o.isDelete = 0 and o.openid = ?",openid);
			PayOrder pay = this.payOrderService.getBaseDao().find("o.isDelete = 0 and o.order = ? and o.state = 0 ", out_trade_no);
			
			if (user == null) {
				throw new NullEntityException("pay user isn't exite");
			}
			if (pay == null) {
				throw new NullEntityException("can not find this order");
			}
			UserAccount userAccount = this.userAccountService.getAccount(pay); 
			if (userAccount == null) {
				// 新建收钱用户账户
				userAccount = new UserAccount();
				userAccount.setUser(pay.getThing().getUser());
				// 加余额
				userAccount.setBalance(pay.getToUserMoney());
				userAccount.setSumBalance(pay.getToUserMoney());
				userAccount.setFreezeBalance(pay.getToUserMoney());
				this.userAccountService.save(userAccount);
				logger.info("create userAccount and write");
			} else {
				// 更新账户
				userAccount.setBalance(userAccount.getBalance().add(pay.getToUserMoney()));
				userAccount.setSumBalance(userAccount.getSumBalance().add(pay.getToUserMoney()));
				userAccount.setFreezeBalance(userAccount.getFreezeBalance().add(pay.getToUserMoney()));
				this.userAccountService.update(userAccount);
				System.out.println("update");
			}
			
			//设置支付用户
			pay.setUser(user);
			pay.setState(PayState.SUCCESS);
			pay.setTip("已支付");
			this.payOrderService.update(pay);
			logger.info("pay success");
			System.out.println("pay success");
			// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
			resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
					+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
			
			
			//给支付用户发模板消息
			String firstInfo = pay.getThing().getUser().getNickName() + " ";
			firstInfo += "已收到你的付款";
			//保留两位小数，四舍五入
			double   originMoney  =   pay.getMoney().setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue(); 
			String orderMoneySumInfo = String.valueOf(originMoney)+"元";
			String orderProductNameInfo = pay.getThing().getTitle();
			String remark = "现在你可以从 "+pay.getThing().getUser().getNickName()+" 手中拿到物品！！";
			WeixinAppToken weixinAppToken = this.weixinAppTokenService.findById(Conf.USED2_ID);
			boolean status =  SendTemplate.sendPaySuccess(openid, "", firstInfo, orderMoneySumInfo, orderProductNameInfo, remark, weixinAppToken.getAccessToken());
			if(status==false){
				logger.info("付款模板发送失败");
			}
			
			//给收款用户发送模板消息
			firstInfo = pay.getUser().getNickName() + " ";
			firstInfo += "已付款";
			//保留两位小数，四舍五入
			originMoney  =   pay.getMoney().setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue(); 
			orderMoneySumInfo = String.valueOf(originMoney)+"元";
			orderProductNameInfo = pay.getThing().getTitle();
			remark = "付款将会在24小时之内到帐,现在你可以把物品给 "+pay.getUser().getNickName()+" 了！！";
			status =  SendTemplate.sendPaySuccess(pay.getThing().getUser().getOpenid(), "", firstInfo, orderMoneySumInfo, orderProductNameInfo, remark, weixinAppToken.getAccessToken());
			if(status==false){
				logger.info("收款模板发送失败");
			}
		} else {
			logger.info("支付失败,错误信息：" + packageParams.get("err_code"));
			resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
					+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
		}
		// ------------------------------
		// 处理业务完毕
		// ------------------------------
		System.out.println("finish");
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
		out.write(resXml.getBytes());
		out.flush();
		out.close();
		
		
	}
}
